#include <assert.h>
#include <unistd.h>
#include "TCPCilent.h"
using namespace std;
static void  OncloseConnect(uv_timer_t *handle)
{
	CTCPClient* clit = (CTCPClient*)(handle->data);
	clit->_session->CloseSession();
	free(handle);
}

CTCPClient::CTCPClient(uv_loop_t* loop) :m_timer(loop)
{
	assert(loop);	
	_loop = loop;	
}

bool CTCPClient::Connect(char* ip, size_t port)
{
	if (_bconn==true)
	{
		printf("have connect svr\n");
		return _bconn;	
	}
	_socket = (uv_tcp_t*)malloc(sizeof(uv_tcp_t));
	uv_tcp_init(_loop, _socket);
	_connect = (uv_connect_t*)malloc(sizeof(uv_connect_t));
	struct sockaddr_in dest;
	uv_ip4_addr(ip, port, &dest);
	_connect->data = this;
	uv_tcp_connect(_connect, _socket, (const sockaddr*)&dest, _OnConnectCb);
	_perrip = string(ip);
	_perrport=port;
}



void CTCPClient::_OnConnectCb(uv_connect_t* req, int status)
{
	CTCPClient* clit = (CTCPClient*)(req->data);
	clit->_bconn = true;
	if (status < 0){
		clit->_bconn = false;		
		if (clit->_interanl_ms > 0){			
			clit->m_timer.StartTimer(clit->_interanl_ms, 0, CTCPClient::_ReConnect, clit);
		}
	}
	else{
		clit->_session = Session::NewSeesion(req->handle);
		clit->_session->SetFlag(true);
	}	
	if (clit->_connStatus){ clit->_connStatus(clit->shared_from_this(), status); }
}
void CTCPClient::CloseConn()
{		
	_interanl_ms=0;
	m_timer.StopTimer();
	if (_session)
	{					
		_session->CloseSession();		
	}	
}


void CTCPClient::OnMsgCall(SessionReadCb msgcb)
{	
	_msgcb = msgcb;
	_session->OnRead([&](SessionPtr s, char* szByte, int len){		
		_msgcb(s, szByte, len);		
	});
}

void CTCPClient::OnClose(SessionCloseCb closecb){
	_closecb=closecb;
	_session->OnClose([this](SessionPtr s){		
		_bconn = false;				
		if (_closecb){ _closecb(s); }		
		if (_interanl_ms > 0){			
			m_timer.StartTimer(_interanl_ms, 0, CTCPClient::_ReConnect, this);			
		}		
	});
 }
void CTCPClient::Write(char* buf, size_t bsize)
{
	_session->Write(buf,bsize);
}



CTCPClient::~CTCPClient()
{			
	free(_connect);
	free(_socket);
	printf("~CTCPClient()\n");
}

